﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Obligatorio2013.Persistencia.Daos;
using Obligatorio2013.Clases;
using Obligatorio2013.Logging;

namespace Obligatorio2013.Modelo
{
    public class AdsController
    {



        #region properties

        private List<Advertisement> adsList = new List<Advertisement>();
        private AdvertisementDAO adDao = new AdvertisementDAO();

        public List<Advertisement> AdsList
        {
            get { return this.adsList; }
        }

        #endregion

        #region Singleton
        private readonly static AdsController _instance = new AdsController();
        public static AdsController Instance { get { return _instance; } }
        private AdsController()
        {
            try
            {
                // TODO: Nico aca inicializar todas las listas
                this.adsList = adDao.getAll().Cast<Advertisement>().ToList();
                Log.Instance.Info("Publicaciones cargadas : " + this.adsList.Count);
            }
            catch (Exception ex) { Log.Instance.Error("Error cargando lista : " + ex.StackTrace); }

        }
        #endregion



        #region methods

        private bool adExists(Advertisement ad)
        {
            if (AdsList != null)
            {
                foreach (Advertisement adv in AdsList)
                {
                    if (adv.Equals(ad))
                        return true;
                }
            }
            return false;
        }

        private void addAdvToList(Advertisement ad)
        {
            if (AdsList == null) adsList = new List<Advertisement>();
            AdsList.Add(ad);
        }


        private void removeAdvList(Advertisement ad)
        {
            if (AdsList != null) { AdsList.Remove(ad); };
        }


        public bool suspendAd(Advertisement ad)
        {
            try
            {
                if (adExists(ad))
                {
                    return adDao.Update(ad);
                }
            }
            catch (Exception ex)
            {
                Log.Instance.Error("Error suspendiendo el aviso. " + ex.Message, ex);
            }
            return false;
        }


        public bool saveAd(Advertisement ad)
        {
            try
            {
                if (!adExists(ad))
                {
                    return adDao.Save(ad);
                }
            }
            catch (Exception ex)
            {
                Log.Instance.Error("Error guardando el aviso. " + ex.Message, ex);
            }
            return false;

        }


        #endregion



        #region validations


        public bool wordCount(string desc, int limit)
        {
            List<string> words = desc.Split(null).ToList();

            if (words.Count <= limit)
            {
                return true;
            }
            return false;
        }


        public double costCalculate(Advertisement ad, Price p)
        {
            double cost = 0;
            double costWordByDay = 0;
            double costWordBySunday = 0;
            int cntDays;
            int cntSundays;

            try
            {
                if (!String.IsNullOrEmpty(ad.description) && !String.IsNullOrEmpty(ad.title))
                {
                    string allWords = ad.title + " " + ad.description;
                    List<string> words = allWords.Split(null).ToList();

                    // Calculo costo diario segun tipo.
                    if (ad.adType.Equals(Advertisement.type.Basic))
                    {
                        costWordByDay = words.Count * p.basicCost;
                    }
                    else
                    {
                        if (String.IsNullOrEmpty(ad.image))
                        {
                            costWordByDay = words.Count * p.premiumCost;
                        }
                        else
                        {
                            // Sumo 40 palabras por tener imagen. (Letra)
                            costWordByDay = (words.Count + 40) * p.premiumCost;
                        }

                    }

                    // obtengo cantidad de dias y de domingos
                    cntDays = getDaysBetweenDates(ad.dateFrom, ad.dateTo);
                    cntSundays = countSundays(ad.dateFrom, ad.dateTo);

                    // obtengo costo dias menos domingos.
                    cost = costWordByDay * (cntDays - cntSundays);
                    // obtengo costo de domingo
                    costWordBySunday = costWordByDay * 2;
                    // obtengo el total. Precio dias + precio domingos.
                    cost = cost + (costWordBySunday * cntSundays);
                }


            }
            catch (Exception ex)
            {
                Log.Instance.Error("Error calculando precio publicacion." + ex.Message, ex);
            }

            return cost;
        }


        private int countSundays(DateTime from, DateTime to)
        {
            int sundays = 0;
            for (var d = from; d <= to; d.AddDays(1))
                if (d.DayOfWeek == DayOfWeek.Sunday) sundays++;
            return sundays;
        }



        private int getDaysBetweenDates(DateTime firstDate, DateTime secondDate)
        {
            return secondDate.Subtract(firstDate).Days;
        }

        #endregion

    }
}